/**
 *
 * @license
 *
 * Copyright (c) Facebook, Inc. and its affiliates.
 */

/**
 * @fileoverview This file defines a function to return the logical form, surface form pair for template objects (single blocks).
 */

import * as Blockly from "blockly/core";

var nestedProperty = require("nested-property");

function getCodeForTemplateObject(surfaceForm, topBlock) {
  var span = window.spans[surfaceForm];
  var startSpan = 0;
  if (!span) {
    // if no span is marked, take the entire surface form as span
    span = surfaceForm;
  }


  // convert the surface form into an array of words
  var surfaceFormArray = surfaceForm.split(" ");

  // convert the span value into an array of words
  var spanArray = span.split(" ");

  // where the span value occurs in the surface form
  startSpan = surfaceFormArray.indexOf(spanArray[0]);

  var endSpan = startSpan + spanArray.length - 1;

  // the skeletal action dictionary generated by the workspace
  var codeString = Blockly.JavaScript.blockToCode(topBlock)[0];
  var code;
  if (codeString) {
    code = JSON.parse(codeString);
  } else {
    // code generated is undefined, initialise it
    code = {};
  }

  // depending on whether the key is a categorical value or a span, set the correct value in the action dictionary

  if (code?.ordinal) {
    // whether ordinal is a span or not depends on the surfaceForm value, so handle seperately
    if (
      surfaceForm == "first" ||
      surfaceForm == "second" ||
      surfaceForm == "third"
    ) {
      code["ordinal"] = span.toUpperCase();
    } else {
      code["ordinal"] = {
        ordinal_span: [[0, [startSpan, endSpan]]],
      };
    }
  }
  else {
    // not a special case
    const spanPaths = ["block_type", "location.steps", "location.has_measure", "repeat.repeat_count", "filters.has_name", "filters.has_size", "filters.has_colour", "num_blocks.block_filters.has_name", "num_blocks.block_filters.has_size", "num_blocks.block_filters.has_colour"];

    const categoricalPaths = ["location.relative_direction", "repeat.repeat_dir"];

    // if a span path exists
    spanPaths.forEach(path => {
      if (nestedProperty.get(code, path)) {
        nestedProperty.set(code, path, [[0, [startSpan, endSpan]]]);
      }
    });

    // if a categorical path exists
    categoricalPaths.forEach(path => {
      if (nestedProperty.get(code, path)) {
        nestedProperty.set(code, path, span);
      }
    });

  }

  return surfaceForm + "    " + JSON.stringify(code, null, 2) + "\n";
}
export default getCodeForTemplateObject;
